package co.edu.udea.iw.prestamos.bl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Service;

import co.edu.udea.iw.prestamos.modelo.dao.UsuarioDAO;
import co.edu.udea.iw.prestamos.modelo.dto.Respuesta;
import co.edu.udea.iw.prestamos.modelo.dto.Usuario;
import co.edu.udea.iw.prestamos.util.ConstantesEstaticas;
import co.edu.udea.iw.prestamos.util.exception.UserNotFoundException;
import co.edu.udea.iw.prestamos.util.logger.Log;
import co.edu.udea.iw.prestamos.util.ppt.LeerPropiedades;
import co.edu.udea.iw.prestamos.util.seguridad.Autenticacion;
import co.edu.udea.iw.prestamos.util.seguridad.TokenGenerator;

/**
 * Lógica de negocio para la gestión de sesiones.
 * 
 * @author Dave Rivera <daverivera90@gmail.com>
 * @since 16-07-2014
 * @version 1.0
 */
@Configurable
@Service("sessionBL")
public class SessionBL {
	
	/**
	 * DAO de la clase Usuario
	 */
	@Autowired
	private UsuarioDAO usuarioDao;
	
	/**
	 * Utilidades para autenticación.
	 */
	@Autowired
	private Autenticacion autenticacion;
	
	/**
	 * Leer propiedades
	 */
	@Autowired
	private LeerPropiedades leerPropiedades;
	
	/**
	 * Cierra la session de un usuario
	 * @param token Identificador del usuario
	 * @return      Respuesta con un mensaje de fin de sesion
	 */
	public Respuesta logout(String token){
		//TODO Pasar el mensaje a property
		return new Respuesta(Respuesta.END_SESSION, ConstantesEstaticas.SESION_CERRAR_SUCCESS);
	}
	
	/**
	 * Abre una session de un usuario
	 * @param  username Nombre de usuario
	 * @param  password Contraseña del usuario
	 * @return          Respuesta con el token de session. Si el usuario o la contraseña no existen o son erroneos envia un mensaje de error.
	 */
	public Respuesta login(String username, String password){
		Respuesta respuesta = new Respuesta();
		
		if (username == null | password == null){
			respuesta.setTipo(Respuesta.ERROR);
			respuesta.setMensaje(leerPropiedades.leerPropiedad(LeerPropiedades.PROPERTIES_RESPUESTAS, ConstantesEstaticas.SESION_LOGIN_VALORES_NULOS));
			return respuesta;
		}
		
		Usuario usuario;
		try {
			usuario = usuarioDao.obtenerUsuarioPorUsername(username);
		} catch (UserNotFoundException e) {
			Log.log(getClass(), 
					leerPropiedades.leerPropiedad(LeerPropiedades.PROPERTIES_EXCEPCIONES, ConstantesEstaticas.SESION_EXCEPCION_USER_NOTFOUND), 
					Log.ERROR, 
					e
				);
			Log.log(getClass(), "Username: " + username, Log.WARNING, null);
			respuesta.setTipo(Respuesta.ERROR);
			return new Respuesta(Respuesta.ERROR, leerPropiedades.leerPropiedad(LeerPropiedades.PROPERTIES_RESPUESTAS, ConstantesEstaticas.SESION_LOGIN_USER_NOTFOUND));
		}
		
		// Asegurar password
		password = autenticacion.generarSecurePassword(password, usuario.getSalt());
		if (usuario.getPassword().compareTo(password) != 0)
			return new Respuesta(Respuesta.ERROR, leerPropiedades.leerPropiedad(LeerPropiedades.PROPERTIES_EXCEPCIONES, ConstantesEstaticas.SESION_EXCEPCION_USER_NOTFOUND));
		
		String token = TokenGenerator.generarToken(username, password);
		Log.log(getClass(), 
				leerPropiedades.leerPropiedad(LeerPropiedades.PROPERTIES_EXCEPCIONES, ConstantesEstaticas.SESION_LOGIN_SUCCESS) + username, 
				Log.INFO, 
				null);
		return new Respuesta(Respuesta.TOKEN, token);
	}
}
